<template>
  <div class="live-container">
    <!-- 操作按钮 -->
    <div class="controls">
      <button :disabled="isInitialized" @click="initialize">初始化</button>
      <button :disabled="!isInitialized || isConnected" @click="joinChannel">加入频道</button>
      <button :disabled="!isConnected" @click="leaveChannel">离开频道</button>
    </div>

    <!-- 本地视频 -->
    <div class="video-wrapper">
      <video ref="localVideo" class="video" autoplay muted playsinline></video>
    </div>

    <!-- 远端视频列表 -->
    <div v-for="user in remoteUsers" :key="user.uid" class="video-wrapper">
      <video ref="setRemoteVideoRef" class="video" autoplay playsinline></video>
      <div class="uid-label">用户 {{ user.uid }}</div>
    </div>

    <!-- 错误提示 -->
    <div v-if="errorMessage" class="error">{{ errorMessage }}</div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onBeforeUnmount } from "vue";
import AgoraRTC, {
  IAgoraRTCClient,
  IAgoraRTCRemoteUser,
  IMicrophoneAudioTrack,
  ICameraVideoTrack,
  UID,
} from "agora-rtc-sdk-ng";

// 配置参数（替换为你的实际值）

const APP_ID = "4487c53bb8a548508ffe17fceb321334"; // 替换为你的 Agora App ID
const CHANNEL = "1231"; // 替换为你的频道名称
const TOKEN =
  "007eJxTYMh8cOy5jNv6uAYdm/ctojPfMs/z/801OWx3hfkhYVZFPhEFBhMTC/NkU+OkJItEUxMLUwOLtLRUQ/O05NQkYyNDY2OTq4o30xsCGRnkGESYGBkgEMRnYTA0MjZkYAAAsXAbdA=="; // 替换为你的 Token
const uid = "123456"; // 可以设置为 null 或指定的 UID
// const optionalInfo = ""; // 确保 optionalInfo 符合要求

// 状态管理
const localVideo = ref<HTMLVideoElement | null>(null);
const localAudioTrack = ref<IMicrophoneAudioTrack | null>(null);
const localVideoTrack = ref<ICameraVideoTrack | null>(null);
const remoteUsers = ref<IAgoraRTCRemoteUser[]>([]);
const remoteVideoElements = new Map<UID, HTMLVideoElement>();
const isInitialized = ref(false);
const isConnected = ref(false);
const errorMessage = ref("");

// Agora客户端实例
let client: IAgoraRTCClient | null = null;

// 初始化SDK
const initialize = async () => {
  try {
    client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

    // 创建本地音视频轨道
    [localAudioTrack.value, localVideoTrack.value] = await Promise.all([
      AgoraRTC.createMicrophoneAudioTrack(),
      AgoraRTC.createCameraVideoTrack(),
    ]);

    // 绑定本地视频
    if (localVideo.value) {
      localVideoTrack.value.play(localVideo.value);
    }

    isInitialized.value = true;
  } catch (error) {
    handleError("初始化失败", error);
  }
};

// 加入频道
const joinChannel = async () => {
  if (!client || !localAudioTrack.value || !localVideoTrack.value) return;

  try {
    // 加入频道
    await client.join(APP_ID, CHANNEL, TOKEN, uid);

    // 发布本地轨道
    await client.publish([
      localAudioTrack.value as IMicrophoneAudioTrack,
      localVideoTrack.value as ICameraVideoTrack,
    ]);
    // 监听远端用户
    client.on("user-published", handleUserPublished);
    client.on("user-unpublished", handleUserUnpublished);

    isConnected.value = true;
  } catch (error) {
    handleError("加入频道失败", error);
  }
};

// 处理远端用户发布流
const handleUserPublished = async (user: IAgoraRTCRemoteUser, mediaType: "audio" | "video") => {
  try {
    // 订阅远端用户
    await client!.subscribe(user, mediaType);

    // 更新远端用户列表
    if (!remoteUsers.value.find((u) => u.uid === user.uid)) {
      remoteUsers.value = [...remoteUsers.value, user];
    }

    // 播放远端视频
    if (mediaType === "video") {
      const videoElement = remoteVideoElements.get(user.uid);
      if (videoElement) {
        user.videoTrack?.play(videoElement);
      }
    }
  } catch (error) {
    handleError("处理远端用户失败", error);
  }
};

// 处理远端用户取消发布
const handleUserUnpublished = (user: IAgoraRTCRemoteUser) => {
  remoteUsers.value = remoteUsers.value.filter((u) => u.uid !== user.uid);
};

// 设置远端视频引用
const setRemoteVideoRef = (el: HTMLVideoElement | null) => {
  if (el) {
    const uid = el.getAttribute("data-uid");
    if (uid) {
      remoteVideoElements.set(uid, el);
    }
  }
};

// 离开频道
const leaveChannel = async () => {
  if (!client) return;

  try {
    // 取消发布本地轨道
    if (localAudioTrack.value)
      await client.unpublish(localAudioTrack.value as IMicrophoneAudioTrack);
    if (localVideoTrack.value) await client.unpublish(localVideoTrack.value as ICameraVideoTrack);

    // 离开频道
    await client.leave();

    // 清理资源
    localAudioTrack.value?.close();
    localVideoTrack.value?.close();
    remoteUsers.value = [];

    isConnected.value = false;
  } catch (error) {
    handleError("离开频道失败", error);
  }
};

// 错误处理
const handleError = (message: string, error: unknown) => {
  const err = error as Error & { code?: string };
  console.error(`${message}:`, err);

  // 常见错误处理
  switch (err.code) {
    case "PERMISSION_DENIED":
      errorMessage.value = "请允许访问麦克风和摄像头";
      break;
    case "INVALID_TOKEN":
      errorMessage.value = "无效的Token，请重新生成";
      break;
    default:
      errorMessage.value = `${message}: ${err.message}`;
  }
};

// 组件卸载时清理
onBeforeUnmount(() => {
  leaveChannel();
  client = null;
});
</script>

<style scoped>
.live-container {
  max-width: 1200px;
  margin: 20px auto;
  padding: 20px;
}

.controls {
  margin-bottom: 20px;
  gap: 10px;
  display: flex;
}

button {
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.video-wrapper {
  position: relative;
  width: 400px;
  height: 300px;
  margin: 10px;
  display: inline-block;
  border: 2px solid #ddd;
}

.video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.uid-label {
  position: absolute;
  bottom: 8px;
  left: 8px;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
}

.error {
  color: #dc3545;
  padding: 10px;
  margin-top: 20px;
  border: 1px solid #dc3545;
  background: #fff0f0;
}
</style>
